﻿#region 版权信息
// ------------------------------------------------------------------------------
// Copyright: (c) 2029  耍嗨科技（成都）有限公司 - Amm
// 项目名称：$SOLUTION/$.Amm.Common
// 文件名称：DateTimeExtensions.cs
// 创建时间：2020093011:11
// 更改时间：2020093011:11
//  ------------------------------------------------------------------------------
#endregion

using System;

namespace Colorful.Furniture.Extensions
{
    public static class DateTimeExtensions
    {
        /// <summary>
        /// 时间戳起始日期，取当地时区
        /// </summary>
        public static DateTime TimestampStart = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1, 0, 0, 0, 0), TimeZoneInfo.Local);

        /// <summary>
        /// DateTime转换为10位时间戳（单位：秒）
        /// </summary>
        /// <param name="dateTime"> DateTime</param>
        /// <returns>10位时间戳（单位：秒）</returns>
        public static long DateTimeToTimeStamp(DateTime dateTime)
        {
            return (long)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
        }

        /// <summary>
        /// DateTime转换为10位时间戳（单位：秒）
        /// </summary>
        /// <param name="dateTime"> DateTime</param>
        /// <returns>10位时间戳（单位：秒）</returns>
        public static long DateTimeToTimeStampH(DateTime dateTime)
        {
            return (long)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
        }
        /// <summary>
        /// 转换为时间戳
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="milliseconds">是否使用毫秒</param>
        /// <returns></returns>
        public static long ToTimestamp(this DateTime dateTime, bool milliseconds = false)
        {
            var timestamp = dateTime.ToUniversalTime() - TimestampStart;
            return (long)(milliseconds ? timestamp.TotalMilliseconds : timestamp.TotalSeconds);
        }

        /// <summary>
        /// 将c# DateTime时间格式转换为Unix13位时间戳格式
        /// </summary>
        /// <param name="time">时间</param>
        /// <returns>long</returns>
        public static long ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000; //除10000调整为13位
            return t;
        }

        /// <summary>
        ///  时间转换成字符串
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string ToNullableDateString(this DateTime? dateTime, string format = "yyyy-MM-dd HH:mm:ss")
        {
            return dateTime.HasValue ? dateTime.Value.ToString(format) : string.Empty;
        }

        /// <summary>
        ///  时间转换成字符串
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string ToDateString(this DateTime dateTime, string format = "yyyy-MM-dd HH:mm:ss")
        {
            return ToNullableDateString(dateTime, format);
        }

        /// <summary>
        /// 获取周几
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public static string GetWeekName(this DateTime datetime)
        {
            var day = (int)datetime.DayOfWeek;
            var week = new[] { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
            return week[day];
        }

        /// <summary>
        /// 获取周几
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public static string GetWeekNameNullable(this DateTime? datetime)
        {
            if (!datetime.HasValue)
                return string.Empty;

            var day = (int)datetime.Value.DayOfWeek;
            var week = new[] { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
            return week[day];
        }

        /// <summary>
        ///  将时间转换成 2022-6-15 00:00:00 或 2022-6-15 23:59:59
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static DateTime ToFormatTime(this DateTime dateTime, int type = 0)
        {
            return dateTime
                .ToString(type == 0 ? "yyyy-MM-dd 00:00:00" : "yyyy-MM-dd 23:59:59")
                .ToDateTime();
        }

        /// <summary>
        ///  获取本周的时间范围
        /// </summary>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetCurrentWeekRange()
        {
            var dt = DateTime.Now;

            var startWeek = dt
                .AddDays(1 - Convert.ToInt32(dt.DayOfWeek.ToString("d")))
                .ToFormatTime(); //本周周一

            var endWeek = startWeek.AddDays(6)
                .ToFormatTime(1);

            return Tuple.Create(startWeek, endWeek);
        }

        /// <summary>
        ///  获取上一周的时间范围
        /// </summary>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetPreWeekRange()
        {
            var dt = DateTime.Now;

            var startWeek = dt
                .AddDays(Convert.ToInt32(1 - Convert.ToInt32(dt.DayOfWeek)) - 7)
                .ToFormatTime(); //上周一

            var endWeek = startWeek.AddDays(6)
                .ToFormatTime(1);

            return Tuple.Create(startWeek, endWeek);
        }

        /// <summary>
        ///  获取指定月的时间范围
        /// </summary>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetMonthRange(this int month)
        {
            var dt = month != 0
                ? DateTime.Now.ToString($"yyyy-{month}-dd").ToDateTime()
                : DateTime.Now;

            var startMonth = dt
                .AddDays(1 - dt.Day)
                .ToFormatTime(); //本月月初

            var endMonth = startMonth
                .AddMonths(1)
                .AddDays(-1)
                .ToFormatTime(1); //本月月末//

            return Tuple.Create(startMonth, endMonth);
        }

        /// <summary>
        ///  获取指定月上个月的时间范围
        /// </summary>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetPreMonthRange(this int month)
        {
            var dt = month != 0
                ? DateTime.Now.ToString($"yyyy-{month}-dd").ToDateTime()
                : DateTime.Now;

            var startMonth = dt
                .ToString("yyyy-MM-01")
                .ToDateTime()
                .AddMonths(-1)
                .ToFormatTime();//上个月1号

            var endMonth = dt
                .ToString("yyyy-MM-01")
                .ToDateTime()
                .AddDays(-1)
                .ToFormatTime(1);//上个月最后一天

            return Tuple.Create(startMonth, endMonth);
        }

        /// <summary>
        ///  获取当天的时间范围
        /// </summary>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetTodayRange()
        {
            var dt = DateTime.Now;

            var startDay = dt.ToString("yyyy-MM-dd").ToDateTime();

            var endDay = dt.ToString("yyyy-MM-dd 23:59:59").ToDateTime();

            return Tuple.Create(startDay, endDay);
        }

        /// <summary>
        ///  获取昨天的时间范围
        /// </summary>
        /// <returns></returns>
        public static Tuple<DateTime, DateTime> GetYesterdayRange()
        {
            var dt = DateTime.Now;

            var startDay = dt.AddDays(-1).ToString("yyyy-MM-dd").ToDateTime();

            var endDay = dt.AddDays(-1).ToString("yyyy-MM-dd 23:59:59").ToDateTime();

            return Tuple.Create(startDay, endDay);
        }
    }
}